/**
 * 
 */
package matrix;


/**
 * @author Yoni Seroussi
 * @author Roei Raviv
 * 
 * Each thread is responsible for the result of a specific element of the
 * product matrix, it calculates the same element (row,col) 
 * on each multiplication. 
 */
public class MatrixMultiplyThread extends Thread {

    private MatricesMultiplierWithBarrier _matrices;

    private int _order;
    private int _col;
    private int _row;
//    private double _matA[][];
    private double _matB[][];
//    private int _numOfMatrices;

    /**
     * @param matrixOrder
     * @param matrices
     *            matrices to multiply (list defines the order of the mult.)
     * @param row
     *            row of elem to calc
     * @param col
     *            col of elem to calc
     */
    public MatrixMultiplyThread(int matrixOrder,
            MatricesMultiplierWithBarrier matrices, int row, int col) {
        _col = col; // col of elem to calc
        _row = row; // row of elem to calc
        _order = matrixOrder;
        _matrices = matrices;
    }

    public void run() {
        double[] rowVals;
        // for each of the matrices
        for (int i = 0 ; i < _matrices.getNumberOfMatrices() ; ++i) {
            // get the current result matrix (or just relevant row)
            rowVals = _matrices.getResultMatrixRow(_row);
            // get the next matrix (phase is sync via the barrier.
            _matB = _matrices.getMatrixToMult(i); // make it return a col
            double elem = 0.0;
            // mult the row by appropriate col
            for (int j = 0 ; j < _order ; ++j) {
                elem += rowVals[j] * _matB[j][_col];
            }
            // wait for all threads to get the a local copy of the needed 
            // row from_result matrix
            _matrices.await(); 
//DEBUG             System.out.println("setting row: " + _row + " col: " + _col + " to " + elem);
            _matrices.setResultElem(_row, _col, elem);
            _matrices.await();
        }
    }
    
    
}
